home *** CD-ROM | disk | FTP | other *** search
- ## -*-Tcl-*-
- # ###################################################################
- # HTML mode - tools for editing HTML documents
- #
- # FILE: "htmlFileUtils.tcl"
- # created: 99-07-20 18.05.44
- # last update: 00-12-22 21.30.57
- # Author: Johan Linde
- # E-mail: <alpha_www_tools@go.to>
- # www: <http://go.to/alpha_www_tools>
- #
- # Version: 3.0
- #
- # Copyright 1996-2001 by Johan Linde
- #
- # This program is free software; you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation; either version 2 of the License, or
- # (at your option) any later version.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License
- # along with this program; if not, write to the Free Software
- # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- #
- # ###################################################################
- ##
-
- #===============================================================================
- # This file contains various file routines for handling HTML links.
- #===============================================================================
-
- #===============================================================================
- # ◊◊◊◊ File routines ◊◊◊◊ #
- #===============================================================================
-
- # Asks for a file and returns the file name including the relative path from
- # current window. For images the width and height are also returned.
- proc html::GetFile {{addtocache 1} {linkFile ""} {errormsg 0}} {
- upvar pathToNewFile newFile
- # get path to this window.
- if {![string length [set this [html::ThisFilePath $errormsg]]]} {return}
-
- # Get the file to link to.
- if {$linkFile == "" && [catch {getfile "Select file to link to."} linkFile]} {
- return
- }
- # For html::LinkToNewFile
- set newFile $linkFile
- # Get URL for this file?
- set link [html::BASEfromPath $linkFile]
- if {[lindex $link 4] == "4"} {
- alertnote "You can't link to a file in an include folder."
- return
- }
- if {[lindex $this 4] == "4" && "[lindex $this 0][lindex $this 1]" == "[lindex $link 0][lindex $link 1]"} {
- set linkTo ":HOMEPAGE:[lindex $link 2]"
- } elseif {[lindex $this 0] == [lindex $link 0]} {
- set linkTo [html::RelativePath "[lindex $this 1][lindex $this 2]" "[lindex $link 1][lindex $link 2]"]
- } else {
- set linkTo [join [lrange $link 0 2] ""]
- }
- set widthheight ""
- if {![file isdirectory $linkFile]} {
- # Check if image file.
- getFileInfo $linkFile arr
- if {$arr(type) == "GIFf" || [file extension $linkFile] == ".gif"} {
- set widthheight [html::GIFWidthHeight $linkFile]
- } elseif {$arr(type) =="JPEG" || $arr(type) == "JFIF" || [file extension $linkFile] == ".jpg"} {
- set widthheight [html::JPEGWidthHeight $linkFile]
- }
- } else {
- append linkTo /
- }
- # Add URL to cache
- if {$addtocache} {html::AddToCache URLs $linkTo}
- return [list $linkTo $widthheight]
- }
-
-
- # Returns the URL to the current window.
- proc html::ThisFilePath {errorMsg} {
-
- set thisFile [html::StrippedFrontWindowPath]
-
- # Look for BASE element.
- if {![catch {search -s -f 1 -r 1 -i 1 -m 0 {<BASE[ \t\r\n]+[^>]*>} 0} res]} {
- set comm 0
- set commPos 0
- while {![catch {search -s -f 1 -r 0 -m 0 -l [lindex $res 0] {<!--} $commPos} cres]} {
- set comm 1
- if {![catch {search -s -f 1 -r 0 -m 0 -l [lindex $res 0] -- {-->} [expr {[lindex $cres 1] + 1}]} cres]} {
- set comm 0
- set commPos [lindex $cres 1]
- } else {
- break
- }
- }
- if {!$comm && [regexp -nocase {HREF[ \t\n\r]*=[ \t\n\r]*("[^"]+"|'[^']+'|[^ \t\r\n>]+)} [getText [lindex $res 0] \
- [lindex $res 1]] dum href]} {
- set href [string trim $href "\"' \t\r\n"]
- if {[catch {html::BASEpieces $href} basestr]} {
- alertnote "Window contains invalid BASE element. Ignored."
- } else {
- return $basestr
- }
- }
- }
-
- # Check if window is saved.
- if {![file exists $thisFile]} {
- switch $errorMsg {
- 0 {
- set etxt "You must save the window. If you save, you will then be prompted\
- for a file to link to."
- }
- 1 {
- set etxt "You must save the window, otherwise it cannot be determined\
- where the link is pointing."
- }
- 2 {
- set etxt "You must save the window, otherwise the link cannot be determined."
- }
- 3 {
- set etxt "You must save the window, otherwise it cannot be determined\
- where the links are pointing."
- }
- 4 {
- set etxt "You must save the window, otherwise it cannot be determined\
- where to upload it."
- }
- }
- if {[lindex [dialog -w 400 -h 100 -t $etxt 10 10 390 60 \
- -b Save 20 70 85 90 \
- -b Cancel 110 70 175 90] 1]} {
- return
- }
-
- if {![catch {saveAs}]} {
- set thisFile [html::StrippedFrontWindowPath]
- } else {
- return
- }
- }
- return [html::BASEfromPath $thisFile]
- }
-
- # Returns URL to file.
- proc html::BASEfromPath {path} {
- global HTMLmodeVars file::separator
- foreach p $HTMLmodeVars(homePages) {
- if {(![set i 0] && [string match [file join [lindex $p $i] *] [file join $path " "]]) ||
- ([llength $p] == 5 && [set i 4] && [string match [file join [lindex $p $i] *] [file join $path " "]])} {
- set path [string range $path [expr {[string length [lindex $p $i]] + 1}] end]
- regsub -all ${file::separator} $path {/} path
- return [list [lindex $p 1] [lindex $p 2] $path [lindex $p 0] $i [lindex $p 4]]
- }
- }
- regsub -all ${file::separator} $path {/} path
- return [list "file:///" "" [string trimleft $path ${file::separator}] "" 0]
- }
-
- # Splits a BASE URL in pieces.
- # NOTE! That this proc returns a shorter list than the proc above, is used in
- # HTML::DblClick to determine if the doc contains a BASE tag.
- proc html::BASEpieces {href} {
- if {[regexp -indices {://} $href css]} {
- if {[set sl [string first / [string range $href [expr {[lindex $css 1] + 1}] end]]] >=0} {
- set base [string range $href 0 [expr {[lindex $css 1] + $sl + 1}]]
- set path [string range $href [expr {[lindex $css 1] + $sl + 2}] end]
- set sl [string last / $path]
- set epath [string range $path [expr {$sl + 1}] end]
- set path [string range $path 0 $sl]
- } else {
- set base [string range $href 0 [lindex $css 1]]
- set path ""
- set epath [string range $href [expr {[lindex $css 1] + 1}] end]
- }
- return [list [html::URLunEscape $base] [html::URLunEscape $path] [html::URLunEscape $epath] ""]
- } else {
- error "Invalid BASE."
- }
- }
-
-
- # Determines width and height of a GIF file.
- proc html::GIFWidthHeight {fil} {
- global tcl_platform
- if {[catch {open $fil r} fid]} {return}
- if {$tcl_platform(platform) != "macintosh"} {
- fconfigure $fid -encoding macRoman
- }
- if {[info tclversion] >= 8.0} {
- fconfigure $fid -translation lf
- }
- seek $fid 6 start
- set width [expr {[html::ReadOne $fid] + 256 * [text::Ascii [read $fid 1]]}]
- set height [expr {[html::ReadOne $fid] + 256 * [text::Ascii [read $fid 1]]}]
- close $fid
- return [list $width $height]
- }
-
- # Extracts width and height of a jpeg file.
- # Algorithm from the perl script 'wwwimagesize' by
- # Alex Knowles, alex@ed.ac.uk
- # Andrew Tong, werdna@ugcs.caltech.edu
- proc html::JPEGWidthHeight {fil} {
- global tcl_platform
- if {[catch {open $fil r} fid]} {return}
- if {$tcl_platform(platform) != "macintosh"} {
- fconfigure $fid -encoding macRoman
- }
- if {[info tclversion] >= 8.0} {
- fconfigure $fid -translation lf
- }
- if {[text::Ascii [read $fid 1]] != 255 || [text::Ascii [read $fid 1]] != 216} {return}
- set ch ""
- while {![eof $fid]} {
- while {[text::Ascii $ch] != 255 && ![eof $fid]} {set ch [read $fid 1]}
- while {[text::Ascii $ch] == 255 && ![eof $fid]} {set ch [read $fid 1]}
- if {[set asc [text::Ascii $ch]] >= 192 && $asc <= 195} {
- seek $fid 3 current
- set height [expr {256 * [text::Ascii [read $fid 1]] + [html::ReadOne $fid]}]
- set width [expr {256 * [text::Ascii [read $fid 1]] + [html::ReadOne $fid]}]
- close $fid
- return [list $width $height]
- } else {
- set ln [expr {256 * [html::ReadOne $fid] + [html::ReadOne $fid] - 2}]
- if {$ln < 0} {break}
- seek $fid $ln current
- }
- }
- close $fid
- }
-
- # Reads one character from an image file.
- # For some mysterious reason 10 and 13 has to be swapped.
- proc html::ReadOne {fid} {
- set c [text::Ascii [read $fid 1]]
- if {[info tclversion] < 8.0} {
- if {$c == 13} {
- set c 10
- } elseif {$c == 10} {
- set c 13
- }
- }
- return $c
- }
-
-
- # Returns toFile including relative path from fromFile.
- proc html::RelativePath {fromFile toFile} {
- # Remove trailing /file from fromFile
- set fromFile [string range $fromFile 0 [expr {[string last / $fromFile] - 1}]]
-
- set fromdir [split $fromFile /]
- set todir [split $toFile /]
-
- # Remove the common path.
- set i 0
- while {[llength $fromdir] > $i && [llength $todir] > $i \
- && [lindex $fromdir $i] == [lindex $todir $i]} {
- incr i
- }
-
- # Insert ../
- foreach f [lrange $fromdir $i end] {
- append linkTo "../"
- }
- # Add the path.
- append linkTo [join [lrange $todir $i end] /]
-
- return $linkTo
- }
-
- # Determine the path to the file "linkTo", as linked from "base path epath".
- proc html::PathToFile {base path epath hpPath linkTo} {
- global HTMLmodeVars file::separator tcl_platform
- # Expand links in include files.
- regsub -nocase {^:HOMEPAGE:} $linkTo "$base$path" linkTo
- # Is this a mailto or news URL or anchor?
- if {[regexp {^(mailto:|news:|javascript:)} [string tolower $linkTo]]} {error $linkTo}
-
- # remove /file from epath
- set sl [string last / $epath]
- set efil [string range $epath [expr {$sl + 1}] end]
- set epath [string range $epath 0 $sl]
-
- # anchor points to efil
- if {[string index $linkTo 0] == "#"} {set linkTo $efil}
-
- # Remove anchor from "linkTo".
- regexp {[^#]*} $linkTo linkTo
-
- # Remove ./ from path
- if {[string range $linkTo 0 1] == "./"} {set linkTo [string range $linkTo 2 end]}
-
- # Relative URL beginning with / is relative to server URL.
- if {[string index $linkTo 0] == "/"} {
- set linkTo "$base[string range $linkTo 1 end]"
- }
-
- # Relative URL?
- if {![regexp {://} $linkTo]} {
- set fromPath [split [string trimright "${path}$epath" /] /]
- set toPath [split $linkTo /]
- # Back down for every ../
- set i 0
- foreach tp $toPath {
- if {$tp == ".."} {
- incr i
- } else {
- break
- }
- }
- if {$i > [llength $fromPath] } {
- error ""
- } else {
- set path1 [join [lrange $fromPath 0 [expr {[llength $fromPath] - $i - 1}]] /]
- if {[string length $path1]} {append path1 /}
- append path1 [join [lrange $toPath $i end] /]
- if {[string match "$path*" $path1] && [string length $hpPath]} {
- set pathTo [string range $path1 [string length $path] end]
- regsub -all {/} $pathTo ${file::separator} pathTo
- set casePath $pathTo
- set pathTo [file join $hpPath $pathTo]
- if {![file isdirectory $pathTo]} {return [list $pathTo $casePath]}
- } elseif {$base == "file:///"} {
- regsub -all {/} $path1 ${file::separator} pathTo
- return [list $pathTo $pathTo]
- }
- set linkTo "$base$path1"
- }
- }
-
- foreach hp [concat $HTMLmodeVars(homePages) [list [list ${file::separator} file:/// "" ""]]] {
- if {[string match "[lindex $hp 1][lindex $hp 2]*" $linkTo] ||
- [string trimright "[lindex $hp 1][lindex $hp 2]" /] == $linkTo} {
- set pathTo [string range $linkTo [string length "[lindex $hp 1][lindex $hp 2]"] end]
- regsub -all {/} $pathTo ${file::separator} pathTo
- set casePath $pathTo
- if {$tcl_platform(platform) == "unix"} {
- set pathTo [file join [lindex $hp 0] $pathTo]
- } else {
- set pathTo [string trimleft [file join [lindex $hp 0] $pathTo] ${file::separator}]
- }
- # If link to folder, add default file.
- if {[file isdirectory $pathTo]} {
- set pathTo [string trimright $pathTo ${file::separator}]
- append pathTo "${file::separator}[lindex $hp 3]"
- set casePath [string trimright $casePath ${file::separator}]
- append casePath "${file::separator}[lindex $hp 3]"
- }
- return [list $pathTo [string trimleft $casePath ${file::separator}]]
- }
- }
- error $linkTo
- }
-
-